//#include <nonstd/expected.hpp>
#include <cxxomfort/base.hpp>
#include <cxxomfort/string.hpp>
#include <cxxomfort/expected.hpp>
#include <cxxomfort/ostream.hpp>
#include <cxxomfort/library/type_name.hpp>
#include <cstdlib>
#include <iostream>
#include <string>

//using namespace nonstd;
//using namespace std::literals;

typedef std::expected<int, std::string> Ecode_t;
void test_expected();

Ecode_t to_int( char const * const text ) 
{
    char * pos = nullptr;
    long value = strtol( text, &pos, 0 );

    if ( pos != text ) return Ecode_t(value);
    else               return std::make_unexpected( std::string("'") + text + "' isn't a number" );
}

int main( int argc, char * argv[] )
{
	using namespace std;
	cxxomfort::output_info(stdout);
	cout<< endl;
	
	test_expected();
	
    char const* text = argc > 1 ? argv[1] : "a42";
    
    Ecode_t ei = to_int( text );
    

    if ( ei.has_value() ) std::cout << "'" << text << "' is " << *ei << ", ";
    else      std::cout << "Error: " << ei.error();
}

void test_expected () {
	using namespace std;
	typedef expected<std::string_view, uint32_t> E1;
	cout<< cxxomfort::library::type_name<string_view>()<< " "<< sizeof(string_view)<< endl;
	cout<< cxxomfort::library::type_name<E1>()<< " "<< sizeof(E1)<< endl;
	typedef expected<double, uint32_t> E2;
	cout<< cxxomfort::library::type_name<double>()<< " "<< sizeof(double)<< endl;
	cout<< cxxomfort::library::type_name<E2>()<< " "<< sizeof(E2)<< endl;
	cout<< "A "<< alignof(uint32_t)<< endl;
	cout<< "A "<< alignof(double)<< endl;
}
